package com.augurit.common.syslog.tool;

import java.util.Date;
import java.util.List;

import org.apache.log4j.spi.LoggingEvent;
import org.springside.modules.queue.BlockingConsumer;
import org.springside.modules.utils.SpringContextHolder;

import com.augurit.common.syslog.service.ISysTraceLogService;
import com.augurit.common.syslog.web.form.SysTraceLogForm;
import com.google.common.collect.Lists;

/**
 * 将Queue中的log4j event写入数据库的消费者任务
 */
public class SysTraceLogWriter extends BlockingConsumer {
	
	public static final String MESSAGE_SEPARATOR = "::";
	private static final int MESSAGE_MAXLENGTH = 900;

	protected int batchSize = 10;
	protected List<LoggingEvent> eventsBuffer = Lists.newArrayList();


	/**
	 * 批量读取事件数量, 默认为10.
	 */
	public void setBatchSize(int batchSize) {
		this.batchSize = batchSize;
	}

	/**
	 * 消息处理函数,将消息放入buffer,当buffer达到batchSize时执行批量更新函数.
	 */
	@Override
	protected void processMessage(Object message) {
		LoggingEvent event = (LoggingEvent) message;
		eventsBuffer.add(event);

		if (logger.isDebugEnabled()) {
			logger.debug("get event, {}", AppenderUtils.convertEventToString(event));
		}

		//已到达BufferSize则执行批量插入操作
		if (eventsBuffer.size() >= batchSize) {
			updateBatch();
		}
	}

	/**
	 * 将Buffer中的事件列表批量插入数据库.
	 */
	@SuppressWarnings("unchecked")
	public void updateBatch() {
		try {
			ISysTraceLogService sysTraceLogService = SpringContextHolder.getBean("sysTraceLogServiceImpl");
			
			for (LoggingEvent event : eventsBuffer) {
				SysTraceLogForm form = new SysTraceLogForm();
				form.setLoggerName(event.getLoggerName());
				form.setLogLevel(event.getLevel().toString());
				form.setLogTime(new Date());
				form.setThreadName(event.getThreadName());

				addMessageAndUserInfo(form, event.getMessage());
				addExceptionInfo(form, event);
				
				sysTraceLogService.save(form);
			}

			//清除已完成的Buffer
			eventsBuffer.clear();
		} catch (Exception e) {
			e.printStackTrace();
			//logger.error("批量提交任务时发生错误.", e);
		}
	}

	/**
	 * 退出清理函数,完成buffer中未完成的消息.
	 */
	@Override
	protected void clean() {
		if (!eventsBuffer.isEmpty()) {
			updateBatch();
		}
		logger.debug("cleaned task {}", this);
	}
	
	/**
	 * 添加日志信息至form对象中
	 * @param form
	 * @param message
	 */
	private void addMessageAndUserInfo(SysTraceLogForm form, Object message){
		if(message != null){
			String str = message.toString();
			int len = str.length();
			
			String msg = null;
			
			if(str.indexOf(MESSAGE_SEPARATOR) > 0){
				String[] msgArray = str.split(MESSAGE_SEPARATOR);
				String userName = msgArray[0];
				msg = msgArray[1];
				form.setUserName(userName);
			}else{
				msg = str;
			}
			
			if(len > MESSAGE_MAXLENGTH)
				form.setMessage(msg.substring(0, MESSAGE_MAXLENGTH) + " ...");
			else
				form.setMessage(msg);
		}
	}
	
	/**
	 * 添加异常信息至form对象中
	 * @param form
	 * @param event
	 */
	private void addExceptionInfo(SysTraceLogForm form, LoggingEvent event){
		String exceptionMsg = "";
		String[] exceptionStack = event.getThrowableStrRep();
		if(exceptionStack != null && exceptionStack.length > 0){
			for(String exception : exceptionStack){
				exceptionMsg += "\r\n" + exception;
			}
		}
		form.setException(exceptionMsg);
	}
}
